package com.freak.kotlinfitnessserver.bt

import android.bluetooth.BluetoothServerSocket
import android.os.Environment
import com.freak.kotlinfitnessserver.util.LogUtil
import com.freak.kotlinfitnessserver.util.ToastUtil
import java.io.DataInputStream
import java.io.File
import java.io.FileInputStream
import java.io.FileOutputStream

class BluetoothServer(bluetoothListener: BluetoothListener) : BaseBluetooth(bluetoothListener) {
    companion object {
        const val TAG: String = "BluetoothServer"

        // 消息标记
        const val FLAG_MSG = 0

        // 文件标记
        const val FLAG_FILE = 1

        val FILE_PATH =
            Environment.getExternalStorageDirectory().absolutePath + "/bluetooth/"
    }

    /**
     * 是否正在发送
     */
    private var isSending = false


    private var mSSocket: BluetoothServerSocket? = null

    override fun init() {
        super.init()
        startListenConnect()
    }

    private fun startListenConnect() {
        try {
            // 加密传输，Android强制执行配对，弹窗显示配对码
            // mSSocket = mBluetoothAdapter.listenUsingRfcommWithServiceRecord(TAG, SPP_UUID)

            // 明文传输(不安全)，无需配对
            mSSocket = mBluetoothAdapter!!.listenUsingInsecureRfcommWithServiceRecord(TAG, SPP_UUID)
            // 监听连接
            val socket = mSSocket!!.accept()
            // 关闭监听，只连接一个设备
            mSSocket!!.close()
            // 循环读取
            startLoopRead(socket)
        } catch (e: Exception) {
            LogUtil.e(TAG, "startListenConnect Exception $e")
            close()
        }
    }


    /**
     * 发送消息
     * @param message 待发送的消息
     */
    fun sendMsg(message: String) {
        isSending = true
        try {
            // 消息标记
            mDataOutputStream!!.writeInt(FLAG_MSG)
            mDataOutputStream!!.writeUTF(message)
            mDataOutputStream!!.flush()
            notifyUI(BluetoothListener.MESSAGE, "发送短消息：$message")
        } catch (e: Throwable) {
            close()
        }
        isSending = false
    }

    fun sendFile(filePath: String) {
        if (checkSend()) {
            return
        }
        isSending = true
        mExecutor.execute {
            try {
                val fileInputStream = FileInputStream(filePath)
                val file = File(filePath)
                // 文件标记
                mDataOutputStream!!.writeInt(FLAG_FILE)
                // 文件名
                mDataOutputStream!!.writeUTF(file.name)
                // 文件长度
                mDataOutputStream!!.writeLong(file.length())
                var r: Int
                val b = ByteArray(4 * 1024)
                notifyUI(
                    BluetoothListener.MESSAGE,
                    "正在发送文件($filePath),请稍后..."
                )
                while (fileInputStream.read(b).also { r = it } != -1) mDataOutputStream!!.write(
                    b,
                    0,
                    r
                )
                mDataOutputStream!!.flush()
                notifyUI(BluetoothListener.MESSAGE, "文件发送完成.")
            } catch (e: Throwable) {
                LogUtil.e(BaseBluetooth.TAG, "sendFile Throwable $e")
                close()
            }
            isSending = false
        }
    }

    private fun checkSend(): Boolean {
        if (isSending) {
            ToastUtil.toastShort("正在发送其它数据,请稍后再发...")
            return true
        }
        return false
    }

    override fun close() {
        super.close()
        try {
            mSSocket!!.close()
        } catch (e: Exception) {
            LogUtil.e(TAG, "close Exception $e")
        }
    }

    override fun readMessage(dataInputStream: DataInputStream) {
        when (dataInputStream.readInt()) {
            // 读取短消息
            FLAG_MSG -> {
                val msg: String = dataInputStream.readUTF()
                notifyUI(BluetoothListener.MESSAGE, "接收短消息：$msg")
            }
            // 读取文件
            FLAG_FILE -> {
                mkdirs(FILE_PATH)
                // 文件名
                val fileName: String = dataInputStream.readUTF()
                // 文件长度
                val fileLen: Long = dataInputStream.readLong()
                // 读取文件内容
                var len: Long = 0
                // 读入缓冲区的总字节数，如果由于已到达流的末尾而没有更多数据，则返回-1。
                var readStatusOrLength: Int
                val byteArray = ByteArray(4 * 1024)
                // 文件输入流
                val fileOutputStream = FileOutputStream(FILE_PATH + fileName)
                notifyUI(
                    BluetoothListener.MESSAGE,
                    "正在接收文件($fileName),请稍后..."
                )
                while (dataInputStream.read(byteArray)
                        .also { readStatusOrLength = it } != -1
                ) {
                    // 写入到文件
                    fileOutputStream.write(byteArray, 0, readStatusOrLength)
                    len += readStatusOrLength.toLong()
                    if (len >= fileLen) {
                        break
                    }
                }
                notifyUI(
                    BluetoothListener.MESSAGE,
                    "文件接收完成(存放在: ${FILE_PATH})"
                )
            }

            else -> {
                val msg: String = dataInputStream.readUTF()
                notifyUI(BluetoothListener.MESSAGE, "接收短消息：$msg")
            }
        }
    }
}